package uoc.ei.practica;

import uoc.ei.tads.Diccionario;
import uoc.ei.tads.DiccionarioAVLImpl;
import uoc.ei.tads.Iterador;

public class ScrabbleManagerImpl implements ScrabbleManager {
	
	private IdentifiedList<ChampionShip> championShips;
	private Diccionario<String, Player> players; 
	

	public ScrabbleManagerImpl() {
		this.championShips= new IdentifiedList<ChampionShip>();
		this.players= new DiccionarioAVLImpl<String, Player>();
	}
	
	@Override
	public void addChampionShip(String championShipId) throws EIException {
		ChampionShip c = this.championShips.getIdentifiedObject(championShipId);
		
		if (c!=null) throw new EIException(Messages.CHAMPIONSHIP_ALREADY_EXISTS);
		
		this.championShips.insertarAlFinal(new ChampionShip(championShipId));

	}

	@Override
	public Iterador<ChampionShip> championShips() throws EIException {
		if (this.championShips.estaVacio()) throw new EIException(Messages.NO_CHAMPIONSHIPS);
			
		return this.championShips.elementos();
	}

	
	@Override
	public void addWord(String championShipId, String word) throws EIException {
		ChampionShip championShip = this.championShips.getIdentifiedObject(championShipId, Messages.CHAMPIONSHIP_NOT_FOUND);
		
		championShip.addWord(word);		
	}
	
	@Override
	public Iterador<Word> words(String championShipId) throws EIException {
		ChampionShip championShip = this.championShips.getIdentifiedObject(championShipId, Messages.CHAMPIONSHIP_NOT_FOUND);

		Iterador<Word> it = championShip.words();
		if (!it.haySiguiente()) throw new EIException(Messages.NO_WORDS);
		
		return it;
	}

	
	@Override
	public void addLetter(String championShipId, String letter, int points, int total)
			throws EIException {
		
		ChampionShip championShip = this.championShips.getIdentifiedObject(championShipId, Messages.CHAMPIONSHIP_NOT_FOUND);

		championShip.addLetter(letter, points, total);			
	}

	@Override
	public Iterador<Letter> letters(String championShipId) throws EIException {
		ChampionShip championShip = this.championShips.getIdentifiedObject(championShipId, Messages.CHAMPIONSHIP_NOT_FOUND);

		Iterador<Letter> it = championShip.letters();			
		return it;
		
	}

	@Override
	public void addGame(String championShipId, String gameId, String nif1, String nif2)
			throws EIException {
		
		ChampionShip c = this.findChampionShip(championShipId);
		if (c==null) throw  new EIException(Messages.CHAMPIONSHIP_NOT_FOUND);
		else
		{
			if (c.isAbierto()==true)throw  new EIException(Messages.INSCRIPTIONS_ALREADY_OPEN);
			else
			{Game
				 g = this.getGame(championShipId, gameId);
				if (g!=null) throw  new EIException(Messages.GAME_ALREADY_EXISTS);
				else
				{
					if (this.findPlayer(nif1)==null | this.findPlayer(nif2)==null)throw  new EIException(Messages.PLAYER_NOT_FOUND);
					else
					{
						if (c.findPlayerregisterd(nif1)==null)throw  new EIException("Player hasn't any inscription (1)");
						if (c.findPlayerregisterd(nif2)==null)throw  new EIException("Player hasn't any inscription (2)");
						c.addGame(gameId, nif1, nif2);
					
					}
				}
			}
		}
		
	}

	@Override
	public Iterador<Game> games(String championShipId) throws EIException {
		ChampionShip c = findChampionShip(championShipId);	  
	    if (c == null)   	throw  new EIException(Messages.CHAMPIONSHIP_NOT_FOUND);
	    return c.games();
		
	}

	
	private Game getGame(String championShipId, String gameId) throws EIException {
		Game gAux;	
		ChampionShip c = findChampionShip(championShipId);
		boolean found = false;
	    if (c == null)   	throw  new EIException(Messages.CHAMPIONSHIP_NOT_FOUND);
	    else{
	    
		if(c.findGame(gameId)!=null)
			found = true;
		gAux=c.findGame(gameId);	
	    }
		
		return  found ? gAux : null;
		
    
		
		
	}
	
	@Override
	public void addCard(String championShipId, String gameId, String letter)
			throws EIException {
		ChampionShip c = findChampionShip(championShipId);
		 if (c == null) throw new EIException(Messages.CHAMPIONSHIP_NOT_FOUND);
		 else
		 {
			 Game g = c.findGame(gameId);
			 if (g == null) throw new EIException(Messages.GAME_NOT_FOUND);
			 else
			 {
				 if (g.getState()==State.CREATED)	g.addCard(letter);
					else throw new EIException(Messages.GAME_ALREADY_OPEN);
			 }
		 }		
	}




	@Override
	public void startGame(String championShipId, String gameId)	throws EIException {

		Game game = this.getGame(championShipId, gameId);
		game.start();	
	}

	
	@Override
	public Iterador<Card> cards(String championShipId, String gameId,
			String playerId) throws EIException {
		ChampionShip c = findChampionShip(championShipId);
		 if (c == null) throw new EIException(Messages.CHAMPIONSHIP_NOT_FOUND);
		 else
		 {
			 Game g = c.findGame(gameId);
			 if (g == null) throw new EIException(Messages.GAME_NOT_FOUND);
			 else
			 {
					Iterador<Card> it = g.cardsPlayer(playerId);
					
					if (it==null || !it.haySiguiente()) throw new EIException(Messages.NO_CARDS); 
					return it;		
			}
		
		 }
			
		
	}

	@Override
	public Iterador<Card> cardsGame(String championShipId, String gameId)
			throws EIException {
		ChampionShip c = findChampionShip(championShipId);
		 if (c == null) throw new EIException(Messages.CHAMPIONSHIP_NOT_FOUND);
		 else
		 {
			 Game g = c.findGame(gameId);
			 if (g == null) throw new EIException(Messages.GAME_NOT_FOUND);
			 else
			 {
					Iterador<Card> it = g.cards();
					
					if (it==null || !it.haySiguiente()) throw new EIException(Messages.NO_CARDS); 
					return it;		
				}
		
		 }
	}

	@Override
	public void finishGame(String championShipId, String gameId)
			throws EIException {
		ChampionShip c = findChampionShip(championShipId);
		 if (c == null) throw new EIException(Messages.CHAMPIONSHIP_NOT_FOUND);
		 else
		 {
			 Game g = c.findGame(gameId);
			 if (g == null) throw new EIException(Messages.GAME_NOT_FOUND);
			 else
			 {
				 g.finishGame();
				 Player p1 = c.findPlayerregisterd(g.getPlayer(1).getNif());
				 Player p2 = c.findPlayerregisterd(g.getPlayer(2).getNif());
				 c.addPlayerToClasificacion(p1);
				 c.addPlayerToClasificacion(p2);
			 }
		}
		
	}

	@Override
	public Iterador<Player> classification(String championShipId)
			throws EIException {
		ChampionShip c = findChampionShip(championShipId);
		 if (c == null) throw new EIException(Messages.CHAMPIONSHIP_NOT_FOUND);
		 else
		 {
			 return c.clasificacion();
		 }
	}	

	@Override
	public void addPlayer(String nif, String name) throws EIException {	
				if(findPlayer(nif) == null)
				{
					Player p = new Player(nif, name);
					players.insertar(nif, p);			
				}		
				else players.consultar(nif).setName(name);
				
		
	}

	@Override
	public Player getPlayer(String nif) throws EIException {
				Player p = findPlayer(nif);
				  
			      if (p == null)
			         throw  new EIException(Messages.PLAYER_NOT_FOUND);

			      return p;
		
	}

	@Override
	public Iterador<Player> players() throws EIException {
		if (players.estaVacio())
			throw new EIException(Messages.NO_PLAYERS);

		return  players.elementos();
		
	}


	@Override
	public void addOrRemoveInscription(String championShipId, String nif) throws EIException {
		ChampionShip c = findChampionShip(championShipId);
		if (c == null) throw  new EIException(Messages.CHAMPIONSHIP_NOT_FOUND);
		else{
			Player p = findPlayer(nif);
			if (p == null) throw  new EIException(Messages.PLAYER_NOT_FOUND);
			else
			{
				if (c.isAbierto()==true)c.addOrRemovePlayerRegisterd(p);
				else throw  new EIException("Inscripcion Cerrada");
				
			}
		}
		
		
		
	}

	@Override
	public Iterador<Player> inscriptions(String championShipId) throws EIException{
		
	ChampionShip c = findChampionShip(championShipId);	  
    if (c == null)   	throw  new EIException(Messages.CHAMPIONSHIP_NOT_FOUND);
    return c.playersRegistered();
	}

	@Override
	public void closeInscription(String championShipId) throws EIException {
		ChampionShip c = findChampionShip(championShipId);	  
	    if (c == null)  throw  new EIException(Messages.CHAMPIONSHIP_NOT_FOUND);
	    Iterador it= inscriptions(championShipId);
	    int i = 0;
	    while(it.haySiguiente()) 
	    {
	        i++;
	        it.siguiente();
	    }
	   
	    c.setNumeroInscripciones(i);	  
	    c.CerrarInscripcion();
		
	}

	@Override
	public int play(String championShipId, String gameId, String playerId,
			int row, int column, char orientation, String word)
			throws EIException {
		int total=0;
		ChampionShip c = findChampionShip(championShipId);
		if (c == null) throw new EIException(Messages.CHAMPIONSHIP_NOT_FOUND);
		 else
		 {
			 Game g = c.findGame(gameId);
			 if (g == null) throw new EIException(Messages.GAME_NOT_FOUND);
			 else
			 { 
				 Player p=c.findPlayerregisterd(playerId);
				 if (p == null)throw new EIException(Messages.PLAYER_NOT_FOUND);
			 	else
			 		{					
			 			if(g.getState()!=State.STARTED)throw new EIException(Messages.GAME_NOT_STARTED);
			 			else{			     
				
						 Word w = c.findWords(word);
						 if (w == null)throw new EIException(Messages.WORD_NO_EXISTS);
						 else
					 {						 
						 int bonusp=1; //Bonus doble y triple palabra
						 int bonusl=1; //Bonus doble y triple letra
						 int totalp=0;						 
						 int pchar=0;
						 word= word.toUpperCase();
						 char[] wChar=word.toCharArray();
						 Board b = g.getBoard();
						 for(int i=0; i < wChar.length;i++)
						 {
							 int mul=0;
							 String let=String.valueOf(wChar[i]);
							 Letter l = c.getLetter(let);
							 pchar=l.getPoints();
							 
							 if(orientation=='V')
							 {
								 mul=b.loadChar(row + i, column, wChar[i]);
								changeCard(championShipId, gameId, playerId, wChar[i]);								
							 }
							 if (orientation=='H')
							 {
								  mul=b.loadChar(row, column + i, wChar[i]);
								 changeCard(championShipId, gameId, playerId, wChar[i]);
								 
							 }
							 switch (mul)
							 {
								 case 5: bonusl=1;
								 break;
								 case 6: bonusl=2;
								 break;
								 case 7: bonusl=3;
								 break;
								 case 8: bonusp=2;
								 break;
								 case 9: bonusp=3;
								 break;
							 }
							 
							 pchar=pchar*bonusl;
							 totalp=totalp+pchar;
						 }
					
						 total=totalp*bonusp;
						 p.setPuntos(p.getPuntos()+total);
						 
					 }
						 
					 }
				 }
			 }
		 }
		
		return total;
	}

	@Override
	public Board showBoard(String championShipId, String gameID)
			throws EIException {
		ChampionShip c = findChampionShip(championShipId);
		 if (c == null) throw new EIException(Messages.CHAMPIONSHIP_NOT_FOUND);
		 else
		 {
			 Game g = c.findGame(gameID);
			 if (g == null) throw new EIException(Messages.GAME_NOT_FOUND);
			 else
			 {
				 return g.getBoard();
			 }
		
		 }
	}
		 
	@Override	
	public Player findPlayer(String nif) {
			
			Player pAux;
			boolean found = false;		
			pAux = players.consultar(nif);
			if(pAux!=null)
				found = true;
			
			return  found ? pAux : null;
		      
		}
	
	@Override	
	public ChampionShip findChampionShip(String championShipId) {
			
		ChampionShip c = null;
		boolean found = false;
		Iterador<ChampionShip> it = championShips.elementos();
		while(it.haySiguiente()==true && found==false)
		{
			c=it.siguiente();
			if(c.getIdentifier().equals(championShipId))
			{
				found = true;	
				
			}
		}
			
		return  found ? c : null;
		}

	@Override	
	public Player findPlayerRegistered(String championShipId, String nif) {
			Player pAux;
			boolean found = false;		
			pAux = players.consultar(nif);
			if(pAux!=null)
				found = true;
			
			return  found ? pAux : null;
		      
		}
	@Override	
	public void changeCard(String championShipId, String gameId,String playerId, char charCard) throws EIException 
		{
			boolean found = false;
			ChampionShip c = findChampionShip(championShipId);
			Game g = c.findGame(gameId);	
			Player p = g.findPlayer(playerId);
			String card=String.valueOf(charCard);
			for(int i=0;i<p.playerCards().length;i++)		
			{
				Card aux = null;
				if(card.equals(p.playerCards(i).toString()))
				{
					
					for(int j=i+1;j<p.playerCards().length;j++)
					{				
						aux=p.playerCards(j);
						p.changeCard(aux, j-1);
					}
					p.popCard(g.pop());
					found=true;
				}
				if(found) break;
			}
			
		}


}
